﻿using System;
using System.Linq.Expressions;

namespace Having.Site.Data.Lambda
{
    /// <summary>
    /// LambdatoSql的接口
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IDataQuery<T> where T : class, new()
    {
        /// <summary>
        /// 返回的结果数据
        /// </summary>
        DataQueryResult Res { get; }

        #region 方法

        /// <summary>
        /// 查询 select查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IDataQuery<T> Select(Expression<Func<T, dynamic>> exp = null) ;
        /// <summary>
        /// 添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="exp">（m=>m.a=="1"）</param>
        /// <returns></returns>
        IDataQuery<T> Insert(Expression<Func<T, bool>> exp);

        /// <summary>
        /// 添加，必须和InsertSelectWhere同用
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        //IDataQuery<T> InsertSelect(Expression<Func<T, string>> exp);

        /// <summary>
        /// 更新
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="exp">（m=>m.a=="1"）</param>
        /// <returns></returns>
        IDataQuery<T> Update(Expression<Func<T, bool>> exp);
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="str">字段=值,字段=值</param>
        /// <returns></returns>
        IDataQuery<T> Update(string str);
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="exp">如果表达式填写，则作为where条件的一部分:（m=>m.a=="1"）</param>
        /// <returns></returns>
        IDataQuery<T> Delete(Expression<Func<T, bool>> exp=null);
        
        ///// <summary>
        ///// 返回树形结构
        ///// </summary>
        ///// <param name="exp"></param>
        ///// <returns></returns>
        //IDataQuery<T> Tree(Expression<Func<T, dynamic>> exp);


        #endregion

        #region join表
        /// <summary>
        /// 左链接表，该表不需要和原来(查询的表)的表做匹配: tb1 Left Join m1 on m1.属性=100
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="exp">（m1=>m1.属性==100）</param>
        /// <returns></returns>
        IDataQuery<T> LeftJoin<T1>(Expression<Func<T1, bool>> exp = null) where T1 : class, new();
        /// <summary>
        /// 左链接表，该表需要和原来(查询的表)的表做匹配 : tb1 Left Join m1 on tb1.属性=m1.属性
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="exp">((tb,m1)=>tb.属性==m1.属性)</param>
        /// <returns></returns>
        IDataQuery<T> LeftJoin<T1>(Expression<Func<T,T1, bool>> exp = null) where T1 : class, new();

        /// <summary>
        /// 右链接表，该表不需要和原来(查询的表)的表做匹配 : tb1 Right Join m1 on m1.属性=100
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="exp">（m1=>m1.属性==100）</param>
        /// <returns></returns>
        IDataQuery<T> RightJoin<T1>(Expression<Func<T1, bool>> exp = null) where T1 : class, new();
        /// <summary>
        /// 右链接表，该表需要和原来(查询的表)的表做匹配 : tb1 Right Join m1 on tb1.属性=m1.属性
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="exp">((tb,m1)=>tb.属性==m1.属性)</param>
        /// <returns></returns>
        IDataQuery<T> RightJoin<T1>(Expression<Func<T, T1, bool>> exp = null) where T1 : class, new();
        /// <summary>
        /// 链接表，该表不需要和原来(查询的表)的表做匹配  : tb1 Inner Join m1 on m1.属性=100
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="exp">（m1=>m1.属性==100）</param>
        /// <returns></returns>
        IDataQuery<T> InnerJoin<T1>(Expression<Func<T1, bool>> exp = null) where T1 : class, new();
        /// <summary>
        /// 链接表，该表需要和原来(查询的表)的表做匹配 : tb1 Inner Join m1 on tb1.属性=m1.属性
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="exp">((tb,m1)=>tb.属性==m1.属性)</param>
        /// <returns></returns>
        IDataQuery<T> InnerJoin<T1>(Expression<Func<T, T1, bool>> exp = null) where T1 : class, new();

        #endregion

        #region 锁

        /// <summary>
        /// With锁
        /// </summary>
        /// <param name="with"></param>
        /// <returns></returns>
        IDataQuery<T> With(SQLWith with);

        #endregion

        #region Where条件

        /// <summary>
        /// where添加
        /// </summary>
        /// <param name="exp">（m=>m.a=="1"）</param>
        /// <returns></returns>
        IDataQuery<T> Where(Expression<Func<T, bool>> exp=null);

        /// <summary>
        /// where添加
        /// </summary>
        /// <param name="where">（例如 a=1 或者insert 下的 select a from table）</param>
        /// <returns></returns>
        IDataQuery<T> Where(string where);



        #endregion

        #region 排序

        /// <summary>
        /// 排序（正派）
        /// </summary>
        /// <param name="exp">(m=>new {m.id})</param>
        /// <returns></returns>
        IDataQuery<T> OrderBy(Expression<Func<T, dynamic>> exp);

        /// <summary>
        /// 正序
        /// </summary>
        /// <param name="name">"id"</param>
        /// <returns></returns>
        IDataQuery<T> OrderBy(string name);
        /// <summary>
        /// 排序（倒排）
        /// </summary>
        /// <param name="exp">(m=>new {m.id})</param>
        /// <returns></returns>
        IDataQuery<T> OrderByDescending(Expression<Func<T, dynamic>> exp);

        /// <summary>
        /// 倒序
        /// </summary>
        /// <param name="name">"id"</param>
        /// <returns></returns>
        IDataQuery<T> OrderByDescending(string name);


        /// <summary>
        /// 排序（正派）,在OrderBy/OrderByDescending后用
        /// </summary>
        /// <param name="exp">(m=>new {m.id})</param>
        /// <returns></returns>
        IDataQuery<T> ThenBy(Expression<Func<T, dynamic>> exp);
        /// <summary>
        /// 排序（倒排），OrderBy/OrderByDescending，增加排序
        /// </summary>
        /// <param name="exp">(m=>new {m.id})</param>
        /// <returns></returns>
        IDataQuery<T> ThenByDescending(Expression<Func<T, dynamic>> exp);

        

        /// <summary>
        /// 排序（倒排），在OrderBy/OrderByDescending后用，增加排序
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        IDataQuery<T> ThenByDescending(string name);
        /// <summary>
        /// 排序（正派）,在OrderBy/OrderByDescending后用
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        IDataQuery<T> ThenBy(string name);

       
        /// <summary>
        /// 随机排序（性能不好，请谨慎使用）
        /// </summary>
        /// <returns></returns>
        IDataQuery<T> OrderByRandom();
        #endregion

        #region 分组

        /// <summary>
        /// group by分组 :GroupBy(m=>new {m.属性1})
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        IDataQuery<T> GroupBy(Expression<Func<T, dynamic>> exp);
        #endregion

        #region 查询的部分path
        /// <summary>
        /// 指定字段
        /// </summary>
        /// <param name="filtername">(多个字段用逗号分开,可以使用子查询)</param>
        /// <returns></returns>
        IDataQuery<T> Filter(string filtername);

        /// <summary>
        /// 指定字段 Filter(m=>new {m.属性1, m.属性2})
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        IDataQuery<T> Filter(Expression<Func<T, dynamic>> exp);
        /// <summary>
        /// 总和
        /// </summary>
        /// <param name="exp">（m=>m.money）</param>
        /// <returns></returns>
        IDataQuery<T> Sum(Expression<Func<T, dynamic>> exp);
        /// <summary>
        /// 最小值
        /// </summary>
        /// <param name="exp">（m=>m.money）</param>
        /// <returns></returns>
        IDataQuery<T> Min(Expression<Func<T, dynamic>> exp);
        /// <summary>
        /// 最大值
        /// </summary>
        /// <param name="exp">（m=>m.money）</param>
        /// <returns></returns>
        IDataQuery<T> Max(Expression<Func<T, object>> exp);
        /// <summary>
        /// 评价值
        /// </summary>
        /// <param name="exp">（m=>m.money）</param>
        /// <returns></returns>
        IDataQuery<T> Avg(Expression<Func<T, dynamic>> exp);
        /// <summary>
        /// 总条数
        /// </summary>
        /// <returns></returns>
        IDataQuery<T> Count(Expression<Func<T, dynamic>> exp=null);
        /// <summary>
        /// 获取前面多少条的记录
        /// </summary>
        /// <param name="rows"></param>
        /// <returns></returns>
        IDataQuery<T> Take(int top);
        #endregion
        #region HAVING 子句
        /// <summary>
        /// 返回having count(属性)>值
        /// </summary>
        /// <param name="exp">（m=>m.属性>值）</param>
        /// <returns></returns>
        IDataQuery<T> HavingCount(Expression<Func<T, bool>> exp);
        /// <summary>
        /// 返回having Sum(属性)>值
        /// </summary>
        /// <param name="exp">（m=>m.属性>值）</param>
        /// <returns></returns>
        IDataQuery<T> HavingSum(Expression<Func<T, bool>> exp);
        /// <summary>
        /// 返回having Avg(属性)>值
        /// </summary>
        /// <param name="exp">（m=>m.属性>值）</param>
        /// <returns></returns>
        IDataQuery<T> HavingAvg(Expression<Func<T, bool>> exp);
        #endregion

        #region 分页
        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="page">第几页</param>
        /// <param name="rows">每页记录数</param>
        /// <returns></returns>
        IDataQuery<T> PageList(int page, int rows);
        #endregion

    }
}
